<?php


namespace App\Libraries\Source\Import;


use App\Jobs\DeclareOrder;
use App\Jobs\DockingJob;
use App\Repositories\Order;
use Carbon\Carbon;
use cszchen\citizenid\Parser;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;

class Client
{
    protected $path = '';

    public function __construct()
    {
        $uploadedFile = request()->file('file');
        $this->path = $uploadedFile->getRealPath();
    }

    /**
     * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     * @throws \Exception
     * @author luffyzhao@vip.126.com
     */
    public function check()
    {
        $error = [];
        $check = new OrderCollection($this->path);
        /**
         * @var $order Collection
         */
        foreach ($check->getOrder() as $order) {

            try {
                DB::beginTransaction();
                // 检查
                $this->checkOrder($order);

                /**
                 * @var $repository Order
                 * @var $oderModel \App\Models\Order
                 */
                $repository = app(Order::class);

                $orderData = $order->toArray();

                try {
                    $oderModel = $repository->first([
                        ['order_code', '=', $orderData['order_code']]
                    ]);
                    // 失败才去更新
                    if ($oderModel->status === 1) {
                        $repository->updateExcel($oderModel, $orderData);
                    }

                } catch (ModelNotFoundException $exception) {
                    $oderModel = $repository->create($order->toArray());
                    DockingJob::dispatch()->delay(Carbon::now()->addMillis());
                }


                DeclareOrder::dispatch($oderModel);


                DB::commit();
            } catch (\Exception $exception) {
                if ($exception->getCode() === '23000') {
                    $error[] = $order['order_code'] . ':已存在！请不要重复上传';
                } else {
                    $error[] = $order['order_code'] . ':' . $exception->getMessage();
                }
                DB::rollBack();
            }
        }

        return $error;
    }

    /**
     * @param Collection $order
     * @throws \Exception
     * @author luffyzhao@vip.126.com
     */
    protected function checkOrder(Collection $order)
    {

        $goodsValue = $order['products']->sum(function ($item) {
            return $item['quantity'] * $item['price'];
        });

        if ($order['goods_value'] !== $goodsValue) {
            throw new \InvalidArgumentException('商品价格不正确');
        }

        if (!$this->checkIDNumber($order['buyer_id_number'])) {
            throw new \InvalidArgumentException('身份证验证不通过');
        }

        if ($goodsValue + $order['tax'] + $order['freight'] - $order['discount'] !== $order['payment']) {
            throw new \InvalidArgumentException('商品货值加税费加运费减优惠不等于支付价额');
        }

        if ($goodsValue * 0.091 !== $order['tax']) {
            throw new \InvalidArgumentException('商品税费计算错误');
        }
    }

    /**
     * @param string $number
     * @return bool
     * @throws \Exception
     * @author luffyzhao@vip.126.com
     */
    protected function checkIDNumber(string $number)
    {
        try {
            $parser = new Parser();
            $parser->setId($number);
            return $parser->isValidate();
        } catch (\Exception $exception) {
            return false;
        }

    }

}